/* 
 * File:   StackTabList.cpp
 * Author: Gab'z
 * 
 * Created on 10 juin 2012, 12:39
 */

#include <list>
#include <sstream>
#include "StackTabList.h"
#include "../model/command/literal/StackList.h"
#include "../controler/Engine.h"

namespace calculator {
    Logger* StackTabList::log = LoggerManager::getInstance()->getLogger("StackTabList");

    StackTabList::StackTabList(const Engine * const engine) : _stackList(engine->getContext()->getStackList()) {
        for (unsigned int i = 0; i < _stackList->size(); i++) {
            std::ostringstream oss;
            oss << "newStackTab... (index = " << i << ") to StackTabList";
            log->trace(oss.str());
            try {
                std::ostringstream oss2;
                oss2 << "pile " << i;
                _tabList.push_back(new StackTabWidget(_stackList->getStack(i)));
            } catch (ContextException) {
                log->error("Error while creating TabList");
            }
        }
        setCurrentTab(_stackList->getCurrentStackIndex());
        log->trace("newStackTab done");
    }

    StackTabList::~StackTabList() {
        for (std::list<StackTabWidget*>::iterator it = _tabList.begin();
                it != _tabList.end();
                it++) {
            delete *it;
        }
        _tabList.clear();
    }

    StackTabWidget* StackTabList::getCurrentTab() const {
        return *_iteratorCurrentTab;
    }

    StackTabWidget* StackTabList::getTab(const unsigned int n) const throw (ViewException) {
        unsigned int index = 0;
        std::list<StackTabWidget*>::const_iterator it = _tabList.begin();
        while (index != n) {
            it++;
            index++;
        }
        if (it == _tabList.end()) throw ViewException("Out of StackList");
        return *it;
    }

    unsigned int StackTabList::getCurrentTabIndex() const {
        unsigned int index = 0;
        std::list<StackTabWidget*>::const_iterator it = _tabList.begin();
        while (it != _iteratorCurrentTab) {
            it++;
            index++;
        }
        return index;
    }

    void StackTabList::setCurrentTab(const unsigned int n) throw (ViewException) {
        log->debug("setCurrentTab...");
        _iteratorCurrentTab = _tabList.begin();
        unsigned int i = 0;
        while (i != n && _iteratorCurrentTab != _tabList.end()) {
            i++;
            _iteratorCurrentTab++;
        }
        if (_iteratorCurrentTab == _tabList.end()) throw ViewException("Out of TabList");
        log->debug("setCurrentTab done");
    }

    void StackTabList::newTab() {
        // on ajoute toujours à la fin
        log->trace("newTab()...");
        StackTabWidget* tab = new StackTabWidget(_stackList->getCurrentStack());
        _iteratorCurrentTab = _tabList.end();
        _tabList.insert(_iteratorCurrentTab, tab);
        _iteratorCurrentTab--;
        log->trace("newTab() done");
    }

    void StackTabList::removeCurrentTab() throw (ViewException) {
        log->trace("removeCurrentTab()...");
        if (_tabList.size() == 1) throw ViewException("Cannot remove one single tab");
        std::list<StackTabWidget*>::iterator it = _iteratorCurrentTab;
        _iteratorCurrentTab--;
        delete *it;
        _tabList.erase(it);
        // après avoir supprimé l'onglet courant, s'il ne s'agissait 
        // pas du dernier on se place sur celui suivant celui supprimé
        if (++_iteratorCurrentTab == _tabList.end()) _iteratorCurrentTab--;
        log->trace("removeCurrentTab() done");
    }

    void StackTabList::duplicateCurrentTab() {
        log->trace("duplicateCurrentTab()...");
        StackTabWidget* tab = new StackTabWidget(_stackList->getCurrentStack());
        std::list<StackTabWidget*>::iterator it = _iteratorCurrentTab;
        it++;
        _tabList.insert(it, tab);
        _iteratorCurrentTab++;
        log->trace("duplicateCurrentTab() done");
    }
}


